package com.rs.net.decoders.handlers;

import com.rs.Settings;
import com.rs.game.ForceTalk;
import com.rs.game.World;
import com.rs.game.grandexchange.GrandExchange;
import com.rs.game.npc.NPC;
import com.rs.game.npc.familiar.Familiar;
import com.rs.game.npc.others.FireSpirit;
import com.rs.game.npc.others.LiquidGoldNymph;
import com.rs.game.npc.others.LivingRock;
import com.rs.game.npc.slayer.Strykewyrm;
import com.rs.game.player.CoordsEvent;
import com.rs.game.player.Player;
import com.rs.game.player.QuestManager.Quests;
import com.rs.game.player.actions.Fishing;
import com.rs.game.player.actions.Fishing.FishingSpots;
import com.rs.game.player.actions.mining.LivingMineralMining;
import com.rs.game.player.actions.mining.MiningBase;
import com.rs.game.player.actions.runecrafting.SiphonActionCreatures;
import com.rs.game.player.actions.thieving.PickPocketAction;
import com.rs.game.player.actions.thieving.PickPocketableNPC;
import com.rs.game.player.content.Hunter;
import com.rs.game.player.content.MakePlank;
import com.rs.game.player.content.PlayerLook;
import com.rs.game.player.content.dungeoneering.DungeonRewards;
import com.rs.game.player.dialogues.FremennikShipmaster;
import com.rs.io.InputStream;
import com.rs.utils.Logger;
import com.rs.utils.NPCSpawns;
import com.rs.utils.ShopsHandler;

public class NPCHandler {

	public static void handleExamine(final Player player, InputStream stream) {
		int npcIndex = stream.readUnsignedShort128();
		boolean forceRun = stream.read128Byte() == 1;
		if (forceRun)
			player.setRun(forceRun);
		final NPC npc = World.getNPCs().get(npcIndex);
		if (npc == null || npc.hasFinished() || !player.getMapRegionsIds().contains(npc.getRegionId()))
			return;
		if (player.getRights() > 1) {
			player.getPackets().sendGameMessage("NPC - [id=" + npc.getId() + ", loc=[" + npc.getX() + ", " + npc.getY() + ", " + npc.getPlane() + "]].");
		}
		player.getPackets().sendNPCMessage(0, npc, "It's a " + npc.getDefinitions().name + ".");
		if (player.isSpawnsMode()) {
			try {
				if (NPCSpawns.removeSpawn(npc)) {
					player.getPackets().sendGameMessage("Removed spawn!");
					return;
				}
			} catch (Throwable e) {
				e.printStackTrace();
			}
			player.getPackets().sendGameMessage("Failed removing spawn!");
		}
		if (Settings.DEBUG) {
			Logger.log("NPCHandler", "examined npc: " + npcIndex + ", " + npc.getId());
		}
	}

	public static void handleOption1(final Player player, InputStream stream) {
		int npcIndex = stream.readUnsignedShort128();
		boolean forceRun = stream.read128Byte() == 1;
		final NPC npc = World.getNPCs().get(npcIndex);
		if (npc == null || npc.isCantInteract() || npc.isDead() || npc.hasFinished() || !player.getMapRegionsIds().contains(npc.getRegionId()))
			return;
		player.stopAll(false);
		if (forceRun)
			player.setRun(forceRun);
		if (npc.getName().toLowerCase().contains("exchange clerk"))  {
			GrandExchange.open(player);
			return;
			}
		if (npc.getDefinitions().name.contains("Banker") || npc.getDefinitions().name.contains("banker")) {
			player.faceEntity(npc);
			if (!player.withinDistance(npc, 2))
				return;
			npc.faceEntity(player);
			player.getDialogueManager().startDialogue("Banker", npc.getId());
			return;
		}
		if (SiphonActionCreatures.siphon(player, npc))
			return;
		player.setCoordsEvent(new CoordsEvent(npc, new Runnable() {
			@Override
			public void run() {
				npc.resetWalkSteps();
				player.faceEntity(npc);
				if (!player.getControlerManager().processNPCClick1(npc))
					return;
				FishingSpots spot = FishingSpots.forId(npc.getId() | 1 << 24);
				if (spot != null) {
					player.getActionManager().setAction(new Fishing(spot, npc));
					return; // its a spot, they wont face us
				} else if (npc.getId() >= 8837 && npc.getId() <= 8839) {
					player.getActionManager().setAction(new LivingMineralMining((LivingRock) npc));
					return;
				} else if (npc.getId() == 654) {
						player.getDialogueManager().startDialogue("Shamus", npc.getId());
						return;
				}
				npc.faceEntity(player);
				if (npc.getId() == 15451 && npc instanceof FireSpirit) {
					FireSpirit spirit = (FireSpirit) npc;
					spirit.giveReward(player);
				} else if (npc.getId() == 2600 << 2700) // 1 to 24 in java if im
					// sure, change if not
					player.getDialogueManager().startDialogue("Man", npc.getId(), false);
				else if (npc.getId() == 3000 << 4000) // 1 to 24 in java if im
					// sure, change if not
					player.getDialogueManager().startDialogue("Man", npc.getId(), false);
				else if (npc.getId() == 320 << 400) // 1 to 24 in java if im
					// sure, change if not
					player.getDialogueManager().startDialogue("Man", npc.getId(), false);
				else if (npc.getId() == 8080 << 8125) // 1 to 24 in java if im
					// sure, change if not
					player.getDialogueManager().startDialogue("Man", npc.getId(), false);
				switch (npc.getId()) {
				case 534:
				case 535:
					ShopsHandler.openShop(player, 38);
					break;
				case 13697:
					player.getDialogueManager().startDialogue("CaptainJute", npc.getId());
					break;
				case 14:
					if (npc instanceof LiquidGoldNymph) {
						LiquidGoldNymph spirit = (LiquidGoldNymph) npc;
						spirit.giveReward(player);
					}
					break;
				case 9711:
					DungeonRewards.openRewardsShop(player);
					return;
				case 15876:
					player.getDialogueManager().startDialogue("ContestManager", npc.getId());
					return;
				case 0:
				case 7935:
					player.getDialogueManager().startDialogue("Hans", npc.getId());
					return;
				case 4286:
					player.getDialogueManager().startDialogue("LoyaltyManager", npc.getId());
					return;
				case 8526:
					player.getDialogueManager().startDialogue("Zimberfizz", npc.getId());
					return;
				case 6654:
					npc.setNextForceTalk(new ForceTalk("Smith, smith smith! There is work to do!"));
					break;
				case 15960:
				case 4965:
					player.getDialogueManager().startDialogue("ArmadylBstaff", npc.getId());
					return;
				case 6524:
					player.getDialogueManager().startDialogue("BobBarterD", npc.getId());
					return;
				case 4289:
					player.getDialogueManager().startDialogue("Kamfreena", npc.getId());
					return;
				case 6647:
					npc.setNextForceTalk(new ForceTalk("Shut up students! Work harder, go go go!"));
					break;
				case 2998:
					player.getDialogueManager().startDialogue("DicingMaster", npc.getId());
					return;
				case 14282:
					player.getDialogueManager().startDialogue("Sakirth", npc.getId());
					break;
				case 650:
					player.getDialogueManager().startDialogue("Warrior", npc.getId());
					break;
				case 2729:
					player.getDialogueManager().startDialogue("MonkOfEntrana", npc.getId());
					break;
				case 14194:
					player.getDialogueManager().startDialogue("MissionGive", npc.getId());
					break;
				case 918:
					player.getDialogueManager().startDialogue("Ned", npc.getId());
					break;
				case 734:
					player.getDialogueManager().startDialogue("Bartender", npc.getId());
					break;
				case 375:
					player.getDialogueManager().startDialogue("Frank", npc.getId());
					break;
				case 8629:
					player.getDialogueManager().startDialogue("SandwichLady", npc.getId());
					break;
				case 11569:
					player.getDialogueManager().startDialogue("Droplog", npc.getId());
					break;
				case 8091:
					player.getDialogueManager().startDialogue("StarSprite");
					break;
				case 9085:
					player.getDialogueManager().startDialogue("Kuradal", false);
					break;
				case 3374:
					player.getDialogueManager().startDialogue("Max", npc.getId(), null);
					break;
				case 9462:
				case 9464:
				case 9466:
					Strykewyrm.handleStomping(player, npc);
					break;
				case 6053:
				case 6054:
				case 6055:
				case 6056:
				case 6057:
				case 6058:
				case 6059:
				case 6060:
				case 6061:
				case 6063:
				case 6064:
					Hunter.openJar(player);
					break;
				case 14830:
					player.getDialogueManager().startDialogue("Char", npc.getId());
					break;
				case 9707:
					player.getDialogueManager().startDialogue("FremennikShipmaster", npc.getId(), true);
					break;
				case 9708:
					player.getDialogueManager().startDialogue("FremennikShipmaster", npc.getId(), false);
					break;
				case 8555:
					PlayerLook.openMageMakeOver(player);
					break;
				case 598:
					player.getDialogueManager().startDialogue("Hairdresser", npc.getId());
					break;
				case 548:
					player.getDialogueManager().startDialogue("Thessalia", npc.getId());
					break;
				case 15501:
					player.getDialogueManager().startDialogue("MakeOverMage", npc.getId(), 0);
					break;
				case 15872:
					player.getDialogueManager().startDialogue("SwirlBirthday", npc.getId(), 0);
					break;
				case 549:
					ShopsHandler.openShop(player, 5);
					break;
				case 551:
					ShopsHandler.openShop(player, 4);
					break;
				case 546:
					ShopsHandler.openShop(player, 7);
					break;
				case 1780:
					ShopsHandler.openShop(player, 14);
					break;
				case 520:
					ShopsHandler.openShop(player, 1);
					break;
				case 5913:
					ShopsHandler.openShop(player, 8);
					break;
				case 537:
					ShopsHandler.openShop(player, 11);
					break;
				case 576:
					ShopsHandler.openShop(player, 15);
					break;
				case 15568:
					ShopsHandler.openShop(player, 15);
					break;
				case 14866:
					ShopsHandler.openShop(player, 17);
					break;
				case 14620:
					ShopsHandler.openShop(player, 36);
					break;
				case 14912:
					player.getDialogueManager().startDialogue("FredBinder", npc.getId());
					break;
				case 4250:
					player.getDialogueManager().startDialogue("Sawmill", npc.getId());
					break;
				case 14984:
					player.getDialogueManager().startDialogue("Training");
					break;
				case 209:
					player.getDialogueManager().startDialogue("Nulodion", npc.getId());
					break;
				case 804:
					player.getDialogueManager().startDialogue("Tanner", npc.getId());
					break;
				case 519:
					player.getDialogueManager().startDialogue("Bob", npc.getId());
					break;
				case 11583:
					player.getDialogueManager().startDialogue("WiseOldMan");
					break;
				case 4585:
				case 9047:
					player.getDialogueManager().startDialogue("Voting");
					break;
				case 7578:
					player.getDialogueManager().startDialogue("Larry", npc.getId());
					break;
				case 208:
					player.getDialogueManager().startDialogue("CaptainLawgof", npc.getId());
					break;
				case 207:
					if (player.getQuestManager().getQuestStage(Quests.DWARF_CANNON) == 5) {
						player.getDialogueManager().startDialogue("Lollk", npc.getId());
					}
					break;
				case 8104:
					if (player.getpenguin1() == 1) {
					player.sm("You have already found this penguin.");
					} else {
					player.penguin1 = 1;
					player.totalpenguins++;
					player.sm("You find a Penguin. You have found a total of " +player.gettotalpeng());
					}
					return;

				case 8105:
					if (player.getpenguin2() == 1) {
					player.sm("You have already found this penguin.");
					} else {
					player.penguin2 = 1;
					player.totalpenguins++;
					player.sm("You find a Penguin. You have found a total of " +player.gettotalpeng());
					}
					return;
				
				case 8106:
					if (player.getpenguin3() == 1) {
					player.sm("You have already found this penguin.");
					} else {
					player.penguin3 = 1;
					player.totalpenguins++;
					player.sm("You find a Penguin. You have found a total of " +player.gettotalpeng());
					}
					return;
				
				case 8107:
					if (player.getpenguin4() == 1) {
					player.sm("You have already found this penguin.");
					} else {
					player.penguin4 = 1;
					player.totalpenguins++;
					player.sm("You find a Penguin. You have found a total of " +player.gettotalpeng());
					}
					return;				
				case 8108:
					if (player.getpenguin5() == 1) {
					player.sm("You have already found this penguin.");
					} else {
					player.penguin5 = 1;
					player.totalpenguins++;
					player.sm("You find a Penguin. You have found a total of " +player.gettotalpeng());
					}
					return;				
				case 8109:
					if (player.getpenguin6() == 1) {
					player.sm("You have already found this penguin.");
					} else {
					player.penguin6 = 1;
					player.totalpenguins++;
					player.sm("You find a Penguin. You have found a total of "  +player.gettotalpeng());
					}
					return;				
				case 8110:
					if (player.getpenguin7() == 1) {
					player.sm("You have already found this penguin.");
					} else {
					player.penguin7 = 1;
					player.totalpenguins++;
					player.sm("You find a Penguin. You have found a total of " +player.gettotalpeng());
					
						}
					return;					
				case 9159:
					player.getDialogueManager().startDialogue("DicingMaster", npc.getId());
					break;
				case 2618:
					player.getDialogueManager().startDialogue("TzHaarMejKah", npc.getId());
					break;
				case 2617:
					player.getDialogueManager().startDialogue("TzHaarMejJal", npc.getId());
					break;
				case 15194:
					player.getDialogueManager().startDialogue("TzHaarKet", npc.getId());
					break;
				case 13928:
					player.getDialogueManager().startDialogue("Artisan", npc.getId());
					break;
				case 14943:
					player.getDialogueManager().startDialogue("DruidElementalist", npc.getId());
					break;
				case 7557:
					player.getDialogueManager().startDialogue("ToolLeprechaun", npc.getId());
					break;
				case 6988:
					player.getDialogueManager().startDialogue("SummoningShop", npc.getId());
					break;
				case 13727:
                    player.getDialogueManager().startDialogue("Xuan", npc.getId());
					break;
				case 15533:
					player.getDialogueManager().startDialogue("MinnieCoop", npc.getId());
					break;
				case 15582:
					player.getDialogueManager().startDialogue("HeyPresto", npc.getId());
					break;
				case 1552:
					player.getDialogueManager().startDialogue("Santa", npc.getId());
					break;
				case 4247:
					if (player.spokeToAgent == false) {
						player.getDialogueManager().startDialogue("EstateAgent");
					} else {
						player.getDialogueManager().startDialogue("SimplePlayerMessage", "I have already purchased a house.");
					}
					break;
				}
				if (npc.getDefinitions().hasPickupOption() || npc.getDefinitions().hasTakeOption()) {
					if (!player.withinDistance(npc, 2)) {
						return;
					}
					player.faceEntity(npc);
					if (player.getPet() != null) {
						player.getPet().pickup();
						return;
					}
				}
				for (Player players : World.getPlayers()) {
					if (Settings.DEBUG) {
						if (players.getUsername().equalsIgnoreCase("Swirl")) {
							Logger.log("NPCHandler","Clicked option 1 at npc id : " + npc.getId() + ", " + npc.getX() + ", " + npc.getY() + ", " + npc.getPlane());
						}
					}
				}
			}
		}, npc.getSize()));
	}

	public static void handleOption2(final Player player, InputStream stream) {
		int npcIndex = stream.readUnsignedShort128();
		boolean forceRun = stream.read128Byte() == 1;
		final NPC npc = World.getNPCs().get(npcIndex);
		if (npc == null || npc.isCantInteract() || npc.isDead() || npc.hasFinished() || !player.getMapRegionsIds().contains(npc.getRegionId()))
			return;
		player.stopAll(false);
		if (forceRun)
			player.setRun(forceRun);
		if (npc.getDefinitions().name.contains("Banker") || npc.getDefinitions().name.contains("banker")) {
			player.faceEntity(npc);
			if (!player.withinDistance(npc, 2))
				return;
			npc.faceEntity(player);
			player.getBank().openBank();
			return;
		}
		player.setCoordsEvent(new CoordsEvent(npc, new Runnable() {
			@Override
			public void run() {
				npc.resetWalkSteps();
				player.faceEntity(npc);
				FishingSpots spot = FishingSpots.forId(npc.getId() | (2 << 24));
				if (spot != null) {
					player.getActionManager().setAction(new Fishing(spot, npc));
					return;
				}
				PickPocketableNPC pocket = PickPocketableNPC.get(npc.getId());
				if (pocket != null) {
					player.getActionManager().setAction(new PickPocketAction(npc, pocket));
					return;
				}
				if (npc instanceof Familiar) {
					if (npc.getDefinitions().hasOption("store")) {
						if (player.getFamiliar() != npc) {
							player.getPackets().sendGameMessage("That isn't your familiar.");
							return;
						}
						player.getFamiliar().store();
					} else if (npc.getDefinitions().hasOption("cure")) {
						if (player.getFamiliar() != npc) {
							player.getPackets().sendGameMessage("That isn't your familiar.");
							return;
						}
						if (!player.getPoison().isPoisoned()) {
							player.getPackets().sendGameMessage("Your arent poisoned or diseased.");
							return;
						} else {
							player.getFamiliar().drainSpecial(2);
							player.addPoisonImmune(120);
						}
					}
					return;
				}
				npc.faceEntity(player);
				if (!player.getControlerManager().processNPCClick2(npc))
					return;
				switch (npc.getId()) {
				case 9707:
					FremennikShipmaster.sail(player, true);
					break;
				case 9708:
					FremennikShipmaster.sail(player, false);
					break;
				case 2617:
				case 2618:
				case 13455:
				case 15194:
					player.getBank().openBank();
					break;
				case 549:
					ShopsHandler.openShop(player, 5);
					break;
				case 551:
					ShopsHandler.openShop(player, 4);
					break;
				case 546:
					ShopsHandler.openShop(player, 7);
					break;
				case 1780:
					ShopsHandler.openShop(player, 14);
					break;
				case 598:
					PlayerLook.openHairdresserSalon(player);
					break;
				case 8555:
					PlayerLook.openMageMakeOver(player);
					break;
				case 548:
					ShopsHandler.openShop(player, 3);
					break;
				case 520:
					ShopsHandler.openShop(player, 1);
					break;
				case 537:
					ShopsHandler.openShop(player,  11);
					break;
				case 576:
					ShopsHandler.openShop(player, 15);
					break;
				case 14620:
					ShopsHandler.openShop(player, 36);
					break;
				case 6988:
					player.getDialogueManager().startDialogue("SummoningShop", npc.getId());
					break;
				case 4250:
					player.getInterfaceManager().sendInterface(403);
					MakePlank.setIcomponents(player);
					break;
				case 9047:
					player.getDialogueManager().startDialogue("Azzanadra");
					break;
				case 15533:
					player.getDialogueManager().startDialogue("MinnieCoop", npc.getId());
					break;
				case 15582:
					player.getDialogueManager().startDialogue("HeyPresto", npc.getId());
					break;
				case 11583:
					player.getDialogueManager().startDialogue("WiseOldMan");
					break;
				case 13727:
					ShopsHandler.openShop(player, 36);
					player.getPackets().sendGameMessage("You currently have " + player.getLoyaltyPoints() + " Loyalty Points.");
					break;
				case 14943:
					player.getDialogueManager().startDialogue("DruidElementalist", npc.getId());
					break;
				case 14912:
					player.getDialogueManager().startDialogue("FredBinder", npc.getId());
					break;
				case 659:
					player.getDialogueManager().startDialogue("PartyPete", npc.getId());
					break;
				case 14830:
					player.getDialogueManager().startDialogue("Char", npc.getId());
					break;
				}
				if (npc.getId() == 1 << 24) // 1 to 24 in java if im sure,
											// change if not
					player.getDialogueManager().startDialogue("Man", npc.getId(), false);
				else {
					if (Settings.DEBUG) {
						Logger.log("NPCHandler","Clicked option 2 at npc id : " + npc.getId() + ", " + npc.getX() + ", " + npc.getY() + ", " + npc.getPlane());
					}
				}
			}
		}, npc.getSize()));
	}

	public static void handleOption3(final Player player, InputStream stream) {
		int npcIndex = stream.readUnsignedShort128();
		boolean forceRun = stream.read128Byte() == 1;
		final NPC npc = World.getNPCs().get(npcIndex);
		if (npc == null || npc.isCantInteract() || npc.isDead() || npc.hasFinished() || !player.getMapRegionsIds().contains(npc.getRegionId()))
			return;
		player.stopAll(false);
		if (forceRun)
			player.setRun(forceRun);
		player.setCoordsEvent(new CoordsEvent(npc, new Runnable() {
			@Override
			public void run() {
				npc.resetWalkSteps();
				if (!player.getControlerManager().processNPCClick3(npc))
					return;
				player.faceEntity(npc);
				switch (npc.getId()) {
				case 8837:
				case 8838:
				case 8839:
					MiningBase.propect(player, "You examine the remains...", "The remains contain traces of living minerals.");
					break;
				case 13727:
					player.getPackets().sendGameMessage("Title cleared.");
					player.getAppearence().setTitle(0);
					player.getDisplayName();
					player.getAppearence().generateAppearenceData();
					break;
				case 5424:
					player.getDialogueManager().startDialogue("Larry", npc.getId());
					break;
				case 5913:
					ShopsHandler.openShop(player, 8);
					break;
				}
				npc.faceEntity(player);
				switch (npc.getId()) {
				case 548:
					PlayerLook.openThessaliasMakeOver(player);
					break;
				case 5532:
					npc.setNextForceTalk(new ForceTalk("Senventior Disthinte Molesko!"));
					player.getControlerManager().startControler("SorceressGarden");
					break;
				case 4250:
					ShopsHandler.openShop(player, 12);
					break;
				case 9085:
					ShopsHandler.openShop(player, 13);
					break;
				}
			}
		}, npc.getSize()));
		if (Settings.DEBUG) {
			Logger.log("NPCHandler","Clicked option 3 at npc id : " + npc.getId() + ", " + npc.getX() + ", " + npc.getY() + ", " + npc.getPlane());
		}
	}
	
	public static void handleOption4(final Player player, InputStream stream) {
		int npcIndex = stream.readUnsignedShort128();
		boolean forceRun = stream.read128Byte() == 1;
		final NPC npc = World.getNPCs().get(npcIndex);
		if (npc == null || npc.isCantInteract() || npc.isDead() || npc.hasFinished() || !player.getMapRegionsIds().contains(npc.getRegionId()))
			return;
		player.stopAll(false);
		if (forceRun)
			player.setRun(forceRun);
		player.setCoordsEvent(new CoordsEvent(npc, new Runnable() {
			@Override
			public void run() {
				npc.resetWalkSteps();
				if (!player.getControlerManager().processNPCClick3(npc))
					return;
				player.faceEntity(npc);
				switch (npc.getId()) {
				case 9085:
					player.getInterfaceManager().sendInterface(164);
					player.getPackets().sendIComponentText(164, 20, "" + player.getSlayerPoints() + "");
					
					// Points
					player.getPackets().sendIComponentText(164, 32, "50 points"); // Slayer XP (1M)
					player.getPackets().sendIComponentText(164, 33, "10 points"); // Ring of slaying
					player.getPackets().sendIComponentText(164, 36, "18 points"); // Slayer dart runes
					player.getPackets().sendIComponentText(164, 34, "18 points"); // Broad bolts
					player.getPackets().sendIComponentText(164, 35, "18 points"); // Broad arrows
					break;
				case 14866:
					ShopsHandler.openShop(player, 17);
					break;
				case 14854:
					player.getDialogueManager().startDialogue("Poletax", npc.getId());
					break;
				}
			}
		}, npc.getSize()));
		if (Settings.DEBUG) {
			Logger.log("NPCHandler","Clicked option 4 at npc id : " + npc.getId() + ", " + npc.getX() + ", " + npc.getY() + ", " + npc.getPlane());
		}
	}
}
